#pragma once

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <functional>
#include <cassert>
// 一个线程类，必要的是，线程id pthread_t（这个可以不用管，直接使用随机值） , 线程名字，线程对应的方法，

namespace ThreadNS
{
    class Thread
    {
    private:

       //由于类中的函数都是自带隐藏的参数即this指针,所以要设置为静态的函数去this指针 
       //    void *startfuc(void * startfuc)
       //    {}

       // 去this指针,这个函数用来新线程消费
       static void *startfuc(void * arvgs)
       {
             
            Thread* _this = static_cast<Thread*>(arvgs);
            // 这才是真正的传入参数
            return _this->_funt(_this->_arvgs);
            // _funt才是真正的phtread_create的函数
       }
    public:

    //typedef void*(*fun_t)(void*);
    typedef std::function<void*(void *)> fun_t;

    Thread()
    {
        char buffer[64];
        snprintf(buffer,sizeof buffer, "thread[%d]" , _count++);
        _name = buffer;
    }

    void start(fun_t funt,void * arvgs)
    {
        _funt = funt;
        _arvgs = arvgs;
        // startfuc是包装的pthread_create的函数
        int n = pthread_create(&_tid,nullptr,startfuc,(void *)this);
        assert(n == 0);
        (void)n;
    }

    std::string getThreadName()
    {
        return _name;
    }

    void join()
    {
        int n = pthread_join(_tid,nullptr);
        assert(n == 0);
        (void)n;
    }

    private:
    // 一个线程应该要有的属性, 名字，线程tid，线程函数，该线程函数要传入的参数
    std::string _name;
    pthread_t _tid;   // _tid直接用随机值即可
    fun_t _funt;
    void* _arvgs;
    static int _count;
    };
    // static初始化的方法
    int Thread :: _count = 1;
};